home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifgate / ifpack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-08  |  4.8 KB  |  254 lines

  1. #include <sys/types.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <errno.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <time.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #ifdef HAS_SYSLOG
  12. #include <syslog.h>
  13. #endif
  14. #include "getopt.h"
  15. #include "lutil.h"
  16. #include "xutil.h"
  17. #include "ftn.h"
  18. #include "config.h"
  19. #include "scanout.h"
  20. #include "version.h"
  21.  
  22. extern int f_lock(char *);
  23. extern void funlock(int);
  24. extern int nodelock(faddr *);
  25. extern int nodeulock(faddr *);
  26. extern int execute(char *,char *,char *,char *,char *,char *);
  27. extern long sequencer(void);
  28. extern char *arcname(faddr *,char);
  29. extern char *floname(faddr *,char);
  30. extern char *splname(faddr *,char);
  31.  
  32. extern char *logname;
  33.  
  34. static int each(faddr*,char,int,char*);
  35. static int packets_ok=0,packets=0;
  36. static char *dow[] = {"su","mo","tu","we","th","fr","sa"};
  37. static char *ext;
  38.  
  39. void usage(name)
  40. char *name;
  41. {
  42.     confusage("");
  43. }
  44.  
  45. int main(argc,argv)
  46. int argc;
  47. char *argv[];
  48. {
  49.     int c,rc;
  50.     time_t tt;
  51.     struct tm *ptm;
  52.  
  53. #ifdef MAILLOG
  54.     logfacility=MAILLOG;
  55. #endif
  56.  
  57.     setmyname(argv[0]);
  58.     while ((c=getopt(argc,argv,"x:l:h")) != -1)
  59.     if (confopt(c,optarg)) switch (c)
  60.     {
  61.         default:    usage(); exit(1);
  62.     }
  63.  
  64.     umask(066);
  65.  
  66.     if ((rc=readconfig()))
  67.     {
  68.         logerr("Error getting configuration, aborting\n");
  69.         return rc;
  70.     }
  71.  
  72.     (void)time(&tt);
  73.     ptm=localtime(&tt);
  74.     ext=dow[ptm->tm_wday];
  75.     debug(3,"today's arcmail extention \"%s\"",ext);
  76.  
  77.     if ((rc=scanout(each)))
  78.     {
  79.         logerr("Error scanning outbound, aborting\n");
  80.         return rc;
  81.     }
  82.  
  83.     if (packets) loginf("processed %d of %d packets, rc=%d",
  84.         packets_ok,packets,rc);
  85.     return 0;
  86. }
  87.  
  88. static int each(addr,flavor,isflo,pktfn)
  89. faddr *addr;
  90. char flavor;
  91. int isflo;
  92. char *pktfn;
  93. {
  94.     int rc=0;
  95.     int absent,needadd;
  96.     int pl;
  97.     char *flofn,*arcfn,*splfn;
  98.     char c,*p;
  99.     char packet[13];
  100.     char pkt[13];
  101.     char buf[512];
  102.     FILE *fp;
  103.     struct flock fl;
  104.     struct stat stbuf;
  105.  
  106.     if (isflo == OUT_FLO) return 0; /* we don't want flo files */
  107.  
  108.     if (isflo == OUT_ARC) /* remove empty non-today files */
  109.     {
  110.         if (strncasecmp(pktfn+strlen(pktfn)-3,ext,2) == 0) return 0;
  111.         if ((stat(pktfn,&stbuf) == 0) && (stbuf.st_size == 0))
  112.         {
  113.             debug(3,"unlink non-todays empty arcmail \"%s\"",
  114.                 pktfn);
  115.             unlink(pktfn);
  116.         }
  117.         return 0;
  118.     }
  119.  
  120.     if (nodelock(addr))
  121.     {
  122.         debug(3,"system %s locked, skipping",ascfnode(addr,0x1f));
  123.         return 0;
  124.     }
  125.  
  126.     debug(3,"packing '%c'-flavor packet \"%s\" to node %s",
  127.         flavor,pktfn,ascfnode(addr,0x1f));
  128.     packets++;
  129.  
  130.     if ((p=strrchr(pktfn,'/')))
  131.     {
  132.         *p='\0';
  133.         if (chdir(pktfn) != 0)
  134.         {
  135.             logerr("$cannot chdir(\"%s\")",pktfn);
  136.             nodeulock(addr);
  137.             return 1;
  138.         }
  139.         strncpy(packet,p+1,12);
  140.         packet[12]='\0';
  141.         *p='/';
  142.     }
  143.     else
  144.     {
  145.         logerr("cannot be: packet name \"%s\" without slash",pktfn);
  146.         nodeulock(addr);
  147.         return 1;
  148.     }
  149.     if ((pl=f_lock(pktfn)) == -1)
  150.     {
  151.         debug(3,"cannot lock packet \"%s\", skipping",pktfn);
  152.         nodeulock(addr);
  153.         return 0;
  154.     }
  155.     arcfn=xstrcpy(arcname(addr,flavor));
  156.     flofn=xstrcpy(floname(addr,flavor));
  157.     splfn=xstrcpy(splname(addr,flavor));
  158.  
  159.     if ((fp=fopen(flofn,"r+")) == NULL)
  160.     if ((fp=fopen(flofn,"w")) == NULL)
  161.     {
  162.         logerr("$could not open flo file \"%s\"",flofn);
  163.         rc=1;
  164.         goto leave;
  165.     }
  166.     fl.l_type=F_WRLCK;
  167.     fl.l_whence=0;
  168.     fl.l_start=0L;
  169.     fl.l_len=0L;
  170.     if (fcntl(fileno(fp),F_SETLK,&fl) < 0)
  171.     {
  172.         if (errno != EAGAIN)
  173.             logerr("$Unable to lock flo file \"%s\"",flofn);
  174.         else
  175.             debug(3,"skipping locked flo file \"%s\"",flofn);
  176.         fclose(fp);
  177.         goto leave;
  178.     }
  179.     if (stat(flofn,&stbuf) != 0)
  180.     {
  181.         debug(3,"$Unable to access flo file \"%s\"",flofn);
  182.         fclose(fp);
  183.         goto leave;
  184.     }
  185.  
  186.     p=arcfn+strlen(arcfn)-1;
  187.     absent=1;
  188.     while (fgets(buf,sizeof(buf)-1,fp))
  189.     {
  190.         if (strncmp(buf+1,arcfn,strlen(arcfn)-1) == 0)
  191.         {
  192.             absent=0;
  193.             c=buf[strlen(arcfn)];
  194.             if (*p < c) *p=c;
  195.             debug(3,"arc file mentioned in flo, new name \"%s\"",
  196.                 arcfn);
  197.         }
  198.     }
  199.  
  200.     needadd=0;
  201.     if (absent)
  202.     {
  203.         debug(3,"no arcmail file mentioned in flo file, create new");
  204.         needadd=1;
  205.         while (stat(arcfn,&stbuf) == 0)
  206.             if (*p == '9') *p='a'; else (*p)++;
  207.     }
  208.     else if (((stat(arcfn,&stbuf) == 0) && (((stbuf.st_size == 0L) ||
  209.         ((maxfsize > 0) && (stbuf.st_size > maxfsize))))) ||
  210.         (stat(splfn,&stbuf) != -1))
  211.     {
  212.         debug(3,"arc file mentioned in flo file, but new requested");
  213.         needadd=1;
  214.         unlink(splfn);
  215.         do
  216.         {
  217.             if (*p == '9') *p='a'; else (*p)++;
  218.         }
  219.         while (stat(arcfn,&stbuf) == 0);
  220.     }
  221.  
  222.     sprintf(pkt,"%08lx.pkt",sequencer());
  223.  
  224.     if (rename(packet,pkt) < 0)
  225.     {
  226.         logerr("$cannot rename \"%s\" to \"%s\"",packet,pkt);
  227.         fclose(fp);
  228.         goto leave;
  229.     }
  230.  
  231.     debug(3,"using .flo file \"%s\", arc file \"%s\", packet \"%s\" -> \"%s\"",
  232.         flofn,arcfn,pktfn,pkt);
  233.     rc=execute(packer,arcfn,pkt,"/dev/null",logname,logname);
  234.     if (rc == 0)
  235.     {
  236.         unlink(pkt);
  237.         if (needadd)
  238.         {
  239.             fprintf(fp,"#%s\n",arcfn);
  240.         }
  241.     }
  242.     else rename(pkt,packet);
  243.     fclose(fp);
  244.  
  245. leave:
  246.     free(arcfn);
  247.     free(flofn);
  248.     free(splfn);
  249.     funlock(pl);
  250.     nodeulock(addr);
  251.     if (rc == 0) packets_ok++;
  252.     return rc;
  253. }
  254.